package com.cysyz.mylib.utils;

//~--- JDK imports ------------------------------------------------------------

import com.cysyz.mylib.utils.myassert.MyAssert;

import java.util.*;

/**
 * Class MyCollectionUtils
 *
 * @version        1.0
 * @author         cui yong    
 */
public abstract class MyCollectionUtils {

    public static class CollectionFrequencyException extends RuntimeException {
        public CollectionFrequencyException(String message) {
            super(message);
        }
    }

    public static class FrequencyCheckEle {
        private String key;
        private Object value;

        public FrequencyCheckEle(String key, Object value) {
            MyAssert.notNullMulti(key, value);
            this.key = key;
            this.value = value;
        }

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public Object getValue() {
            return value;
        }

        public void setValue(Object value) {
            this.value = value;
        }
    }

    /**
     * 验证集合中元素的重复性，如果重复字数大于等于frequencyTimes，抛出异常
     * @param frequencyAbleCollection 需要验证的集合
     * @param frequencyTimes 重复的字数
     */
    public static void checkFrequency(Collection<FrequencyCheckEle> frequencyAbleCollection, int frequencyTimes) {


        Collection<FrequencyCheckEle> frequencyCollection = MyCollectionUtils.getFrequencyCollection(frequencyAbleCollection, frequencyTimes);

        StringBuilder sb = new StringBuilder();
        sb.append("value duplicated:");
        for (FrequencyCheckEle frequencyEle : frequencyCollection) {
            sb.append("\n");
            sb.append(frequencyEle.getValue());
        }
        if (!frequencyCollection.isEmpty()) {
            throw new CollectionFrequencyException(sb.toString());
        }
    }

    /**
     * 验证集合中元素的重复性，如果重复字数大于等于frequencyTimes，抛出异常
     * @param frequencyAbleCollection 需要验证的集合
     */
    public static void checkFrequency(Collection<FrequencyCheckEle> frequencyAbleCollection) {
        MyCollectionUtils.checkFrequency(frequencyAbleCollection, 2);
    }

    public static Collection<FrequencyCheckEle> getFrequencyCollection(Collection<FrequencyCheckEle> frequencyCheckCollection, int frequencyTimes) {
        Set<String> weiyiKeySet = new HashSet<String>();
        List<String> frequencyAbleKeyList = new ArrayList<String>();

        for (FrequencyCheckEle frequencyCheckEle : frequencyCheckCollection) {
            frequencyAbleKeyList.add(frequencyCheckEle.getKey());
            weiyiKeySet.add(frequencyCheckEle.getKey());
        }

        Collection<FrequencyCheckEle> frequencyEleSet = new HashSet<FrequencyCheckEle>();

        for (String weyiKey : weiyiKeySet) {
            if (Collections.frequency(frequencyAbleKeyList, weyiKey) >= frequencyTimes) {
                for (FrequencyCheckEle frequencyCheckEle : frequencyCheckCollection) {
                    if (frequencyCheckEle.getKey().equals(weyiKey)) {
                        frequencyEleSet.add(frequencyCheckEle);
                    }
                }
            }
        }

        return frequencyEleSet;
    }

    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        Collections.sort(list);
    }

    public static <T> List<T> nCopies(int n, T o) {
        return Collections.nCopies(n, o);
    }

    public static void shuffle(List<?> list, Random rnd) {
        Collections.shuffle(list, rnd);
    }

    public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) {
        return Collections.binarySearch(list, key, c);
    }

    public static <T extends Comparable<? super T>> T min(Collection<? extends T> coll) {
        return Collections.min(coll);
    }

    public static int lastIndexOfSubList(List<?> source, List<?> target) {
        return Collections.lastIndexOfSubList(source, target);
    }

    public static <T> Queue<T> asLifoQueue(Deque<T> deque) {
        return Collections.asLifoQueue(deque);
    }

    public static <K, V> Map<K, V> emptyMap() {
        return Collections.emptyMap();
    }

    public static <E> Collection<E> checkedCollection(Collection<E> c, Class<E> type) {
        return Collections.checkedCollection(c, type);
    }

    public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) {
        return Collections.binarySearch(list, key);
    }

    public static <T> ListIterator<T> emptyListIterator() {
        return Collections.emptyListIterator();
    }

    @SafeVarargs
    public static <T> boolean addAll(Collection<? super T> c, T... elements) {
        return Collections.addAll(c, elements);
    }

    public static void swap(List<?> list, int i, int j) {
        Collections.swap(list, i, j);
    }

    public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s, Class<E> type) {
        return Collections.checkedSortedSet(s, type);
    }

    public static <T> List<T> singletonList(T o) {
        return Collections.singletonList(o);
    }

    public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) {
        return Collections.checkedSet(s, type);
    }

    public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
        return Collections.newSetFromMap(map);
    }

    public static <T> Enumeration<T> emptyEnumeration() {
        return Collections.emptyEnumeration();
    }

    public static int indexOfSubList(List<?> source, List<?> target) {
        return Collections.indexOfSubList(source, target);
    }

    public static <T> Set<T> synchronizedSet(Set<T> s) {
        return Collections.synchronizedSet(s);
    }

    public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
        return Collections.reverseOrder(cmp);
    }

    public static <E> List<E> checkedList(List<E> list, Class<E> type) {
        return Collections.checkedList(list, type);
    }

    public static <K, V> Map<K, V> singletonMap(K key, V value) {
        return Collections.singletonMap(key, value);
    }

    public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s) {
        return Collections.synchronizedSortedSet(s);
    }

    public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
        return Collections.max(coll, comp);
    }

    public static <K, V> SortedMap<K, V> checkedSortedMap(SortedMap<K, V> m, Class<K> keyType, Class<V> valueType) {
        return Collections.checkedSortedMap(m, keyType, valueType);
    }

    public static <K, V> SortedMap<K, V> synchronizedSortedMap(SortedMap<K, V> m) {
        return Collections.synchronizedSortedMap(m);
    }

    public static <T> Set<T> emptySet() {
        return Collections.emptySet();
    }

    public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll) {
        return Collections.max(coll);
    }

    public static <T> List<T> synchronizedList(List<T> list) {
        return Collections.synchronizedList(list);
    }

    public static <T> Enumeration<T> enumeration(Collection<T> c) {
        return Collections.enumeration(c);
    }

    public static void rotate(List<?> list, int distance) {
        Collections.rotate(list, distance);
    }

    public static void reverse(List<?> list) {
        Collections.reverse(list);
    }

    public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {
        return Collections.min(coll, comp);
    }

    public static <T> void sort(List<T> list, Comparator<? super T> c) {
        Collections.sort(list, c);
    }

    public static <T> Set<T> singleton(T o) {
        return Collections.singleton(o);
    }

    public static <T> Collection<T> synchronizedCollection(Collection<T> c) {
        return Collections.synchronizedCollection(c);
    }

    public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
        return Collections.unmodifiableCollection(c);
    }

    public static <T> void copy(List<? super T> dest, List<? extends T> src) {
        Collections.copy(dest, src);
    }

    public static <K, V> Map<K, V> unmodifiableMap(Map<? extends K, ? extends V> m) {
        return Collections.unmodifiableMap(m);
    }

    public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) {
        return Collections.checkedMap(m, keyType, valueType);
    }

    public static boolean disjoint(Collection<?> c1, Collection<?> c2) {
        return Collections.disjoint(c1, c2);
    }

    public static <T> List<T> emptyList() {
        return Collections.emptyList();
    }

    public static <T> void fill(List<? super T> list, T obj) {
        Collections.fill(list, obj);
    }

    public static int frequency(Collection<?> c, Object o) {
        return Collections.frequency(c, o);
    }

    public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) {
        return Collections.unmodifiableSortedSet(s);
    }

    public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal) {
        return Collections.replaceAll(list, oldVal, newVal);
    }

    public static <T> ArrayList<T> list(Enumeration<T> e) {
        return Collections.list(e);
    }

    public static <K, V> Map<K, V> synchronizedMap(Map<K, V> m) {
        return Collections.synchronizedMap(m);
    }

    public static <K, V> SortedMap<K, V> unmodifiableSortedMap(SortedMap<K, ? extends V> m) {
        return Collections.unmodifiableSortedMap(m);
    }

    public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
        return Collections.unmodifiableSet(s);
    }

    public static void shuffle(List<?> list) {
        Collections.shuffle(list);
    }

    public static <T> List<T> unmodifiableList(List<? extends T> list) {
        return Collections.unmodifiableList(list);
    }

    public static <T> Iterator<T> emptyIterator() {
        return Collections.emptyIterator();
    }

    public static <T> Comparator<T> reverseOrder() {
        return Collections.reverseOrder();
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
